include(['PClass'], 

function(){
	declare('InputManager');
	
	InputManager = PClass.create({
		buttonStates : null,
		listenerMap  : null,
		_lock : null,
		
		init : function(){
			this.buttonStates = {};
			this.listenerMap  = {};	
			this._lock = null;
		},
		lock : function(listener){
			this._lock = listener;
		},		
		buttonDown : function(x,y, bId){
			//console.log(x +", " +y);
			var bstate = {id: bId, x:x, y:y, active:true};
			this.buttonStates[bId] = bstate;
			
			var event = {name:'onButtonDown', x:x, y:y, bId:bstate, buttons:this.buttonStates};
			this.notifyListeners(event);
		},
		buttonUp : function(x,y, bId){
			var bstate = this.buttonStates[bId]; 
			if( bstate ){
				var event = {name:'onButtonUp', x:x, y:y, bId:bstate, buttons:this.buttonStates};
				this.notifyListeners(event);
				
				bstate.x = -1;
				bstate.y = -1;
				bstate.active = false;
			}
		},
		cursorMove : function(x,y, bId){
			var bstate = this.buttonStates[bId];
			var button = null;
			if( bstate && bstate.active ){
				button = bstate;
			}
			var event = {name:'onMove', x:x, y:y, bId:button, buttons:this.buttonStates};
			this.notifyListeners(event);
		},
		notifyListeners : function(event){
			for( var member in this.listenerMap ){
				if( this._lock && member != this._lock)
					continue;
				var listener = this.listenerMap[member];
				if(listener[event.name])
					listener[event.name](event);
			}
		},
		addListener : function(key, listener, eventName){
			//Filter to specific event
			if( eventName ){
				var bckup = listener;
				listener = {};
				listener[eventName] = function(){
					bckup(arguments);
				};
			}
			this.listenerMap[key] = listener;
		}
	});
	
	MouseInputDevice = PClass.create({
		offset : null,	
		init : function(inputManager, element){
			this.offset = {x:0, y:0};
			
			element = element || document;
			
			var selfish = this;
			
			element.addEventListener("mousedown", function(e){ 
				inputManager.buttonDown(e.clientX + selfish.offset.x, e.clientY + selfish.offset.y, e.button);
				e.preventDefault();
			}, true);
			element.addEventListener("mouseup", function(e){ 
				inputManager.buttonUp(e.clientX + selfish.offset.x, e.clientY + selfish.offset.y, e.button);
				e.preventDefault();
			}, true);
			element.addEventListener("mousemove", function(e){ 
				inputManager.cursorMove(e.clientX + selfish.offset.x, e.clientY + selfish.offset.y, e.button);
			}, true);
			element.addEventListener("oncontextmenu", function(e){
				return false;
			}, true);
		}
	});
	
	TouchInputDevice = PClass.create({
		offset : null,
		init : function(inputManager, element){
			this.offset = {x:0, y:0};
			
			element = element || document;
			
			var selfish = this;
			
			element.addEventListener("touchstart", function(te){
				for(var i=0; i <te.changedTouches.length; i++){
					e = te.changedTouches[i];
					inputManager.buttonDown(e.clientX + selfish.offset.x, e.clientY + selfish.offset.y, e.identifier);
				}
				te.preventDefault();
			});
			element.addEventListener("touchend", function(te){
				for(var i=0; i <te.changedTouches.length; i++){
					e = te.changedTouches[i];
					inputManager.buttonUp(e.clientX + selfish.offset.x, e.clientY + selfish.offset.y, e.identifier);
				}
				te.preventDefault();
			});
			element.addEventListener("touchmove", function(te){
				for(var i=0; i <te.changedTouches.length; i++){
					e = te.changedTouches[i];
					inputManager.cursorMove(e.clientX + selfish.offset.x, e.clientY + selfish.offset.y, e.identifier);
				}
				te.preventDefault();
			});
		}
	}, 'TouchInputDevice');
	
	KeyboardInputDevice = PClass.create({
		offset : {x:0, y:0},
		init : function(inputManager, element){
			element = element || document;
			var joystick = 'keyboard';
			var offset = {x:0, y:0};
			element.addEventListener('keydown', function(event){
				var speed = 15;
				var bId = event.keyCode;
				if(event.keyCode == '38' || event.keyCode == '104' || event.keyCode == '87'){//UP
					offset.y = -speed;
					bId = joystick;
				}else if( event.keyCode == '40' || event.keyCode == '98' || event.keyCode == '83'){//Down
					offset.y = speed;
					bId = joystick;
				}else if( event.keyCode == '37' || event.keyCode == '100' || event.keyCode == '65'){//Left
					offset.x = -speed;
					bId = joystick;
				}else if( event.keyCode == '39' || event.keyCode == '102' || event.keyCode == '68'){//Right
					offset.x = speed;
					bId = joystick;
				}else if( event.keyCode == '13' ){
					
				}
				inputManager.buttonDown(0, 0, bId);
				if( bId == joystick ){
					inputManager.cursorMove(offset.x, offset.y, bId);
				}
				event.preventDefault();
				//Cancel the action to ensure we don't scroll
				return false;
			}, false);
			element.addEventListener('keyup', function(event){
				var bId = event.keyCode;
				if(event.keyCode == '38' || event.keyCode == '104' || event.keyCode == '87'){//UP
					offset.y = 0;
					bId = joystick;
				}else if( event.keyCode == '40' || event.keyCode == '98' || event.keyCode == '83'){//Down
					offset.y = 0;
					bId = joystick;
				}else if( event.keyCode == '37' || event.keyCode == '100' || event.keyCode == '65'){//Left
					offset.x = 0;
					bId = joystick;
				}else if( event.keyCode == '39' || event.keyCode == '102' || event.keyCode == '68'){//Right
					offset.x = 0;
					bId = joystick;
				}
				if( bId == joystick ){
					inputManager.cursorMove(offset.x,offset.y, bId);
					if( !offset.x && !offset.y )
						inputManager.buttonUp(0,0, bId)
				}else{
					inputManager.buttonUp(0,0, bId)
				}
				event.preventDefault();
				
			}, false);
		}
	});

});